package com.xjj.service.service.serviceimpl;

import cn.hutool.core.util.RandomUtil;
import com.cloopen.rest.sdk.BodyType;
import com.cloopen.rest.sdk.CCPRestSmsSDK;
import com.xjj.service.captcha.SmsProperties;
import com.xjj.service.service.SmsService;
import com.xjj.util.exception.BusinessException;
import com.xjj.util.exception.RepeatedSmsException;
import com.xjj.util.utils.RegexUtils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import static com.xjj.util.utils.RedisConstants.LOGIN_CODE_KEY;


@Service
@Slf4j
public class SmsServiceImpl implements SmsService {
    @Resource
    RedisTemplate<String, Object> redisTemplate;

    //短信发送
    @Override
    public void send(String tel) {
        CCPRestSmsSDK sdk = getCcpRestSmsSDK();

        // 1、校验手机号格式
        if (RegexUtils.isPhoneInvalid(tel)) {
            throw new BusinessException("手机号格式不正确");
        }

        // 2、校验验证码是否仍可使用
        String redisKey = LOGIN_CODE_KEY + tel;
        Object o = redisTemplate.opsForValue().get(redisKey);
        if (o != null) {
            throw new RepeatedSmsException("您上次的验证码仍可使用");
        }

        // 3、生成4位随机数字验证码
        String code = RandomUtil.randomNumbers(4);

        // 4、发送短信
        //  短信里的变量，验证码、几分钟内有效
        String[] datas = {code, "3"};
        HashMap<String, Object> result = sdk.sendTemplateSMS(tel, "1", datas);

        // 5、发送失败
        if (!"000000".equals(result.get("statusCode"))) {
            //异常返回输出错误码和错误信息（或log.error 打印到日志）
            log.debug(">>>>>>>>> 短信发送失败: status -> {} , msg -> {}", result.get("statusCode"), result.get("statusMsg"));
            // 自定义的统一异常处理，如果出错了会发给前端
            throw new BusinessException("短信发送失败");
        }

        // 6、发送成功
        // 将验证码存入redis
        redisTemplate.opsForValue().set(LOGIN_CODE_KEY + tel, code, 3, TimeUnit.MINUTES);

        log.debug(">>>>>>>>> 短信发送成功：tel -> {} , code -> {}", tel, code);
    }


    @NotNull
    private CCPRestSmsSDK getCcpRestSmsSDK() {
        // 配置账号信息
        CCPRestSmsSDK sdk = new CCPRestSmsSDK();
        sdk.init(SmsProperties.SERVER_IP, SmsProperties.SERVER_PORT);
        sdk.setAccount(SmsProperties.ACCOUNT_SID, SmsProperties.ACCOUNT_Token);
        sdk.setAppId(SmsProperties.APP_ID);
        sdk.setBodyType(BodyType.Type_JSON);
        return sdk;
    }
}